﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using InfoJetSoft.Service.Entity;

//CID 0825 //2011.03.06 //Begin
namespace InfoJetSoft.Service.XPath
{
    class BindingPathUtil
    {
        public static string CalculateRelativePath(XmlNode baseNode, XmlNode relativeNode)
        {
            if (baseNode.Equals(relativeNode))
            {
                return ".";
            }
            List<XmlNode> baseNodeList = GetNodeList(baseNode);
            List<XmlNode> relativeNodeList = GetNodeList(relativeNode);

            int sameNodeCount = GetSameNodeCount(baseNodeList, relativeNodeList);

            for (int i = 0; i < sameNodeCount; i++)
            {
                baseNodeList.RemoveAt(0);
                relativeNodeList.RemoveAt(0);
            }

            StringBuilder buffer = new StringBuilder();
            foreach (XmlNode curBaseNode in baseNodeList)
            {
                if (buffer.Length <= 0)
                {
                    buffer.Append("..");
                }
                else
                {
                    buffer.Append("/..");
                }
            }

            foreach (XmlNode curRelativeNode in relativeNodeList)
            {
                //CID 0889 //2011.05.24 //Begin
                if (buffer.Length > 0)
                {
                    buffer.Append("/");
                }
                if (curRelativeNode is XmlAttribute)
                {
                    buffer.Append("@" + curRelativeNode.Name);
                }
                else
                {
                    buffer.Append(curRelativeNode.Name);
                }
                //CID 0889 //2011.05.24 //End
            }

            return buffer.ToString();
        }

        private static List<XmlNode> GetNodeList(XmlNode node)
        { 
            List<XmlNode> nodeList = new List<XmlNode>();
            nodeList.Insert(0, node);
            XmlNode parentNode = GetOwnerNode(node);
            while (parentNode != null)
            {
                nodeList.Insert(0, parentNode);
                parentNode = GetOwnerNode(parentNode);
            }
            return nodeList;
        }

        private static int GetSameNodeCount(List<XmlNode> nodeList1, List<XmlNode> nodeList2)
        {
            int sameNodeCount = 0;
            for (int i = 0; true; i++)
            {
                if (i < nodeList1.Count && i < nodeList2.Count)
                {
                    XmlNode node1 = nodeList1[i];
                    XmlNode node2 = nodeList2[i];
                    if (node1.Equals(node2))
                    {
                        sameNodeCount++;
                        continue;
                    }
                }
                else
                {
                    break;
                }
            }
            return sameNodeCount;
        }

        private static XmlNode GetOwnerNode(XmlNode node)
        {
            if (node is XmlAttribute)
            {
                return ((XmlAttribute)node).OwnerElement;
            }
            else
            {
                return node.ParentNode;
            }
        }
    }
}
//CID 0900 //2011.05.11 //End